home *** CD-ROM | disk | FTP | other *** search
/ LiquidLibrary 2005 September / LiquidLibrary 2005 Sep - Disc 1.iso / pc / Portfolio Browser / Filters / PDF / LIB / pdf_ops.ps < prev    next >
Text File  |  2003-01-03  |  16KB  |  511 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is licensed to a single customer by Artifex Software Inc.
  3. % under the terms of a specific OEM agreement.
  4.  
  5. % $RCSfile$ $Revision$
  6. % Definitions for most of the PDF operators.
  7.  
  8. .currentglobal true .setglobal
  9.  
  10. % Define pdfmark.  Don't allow it to be bound in.
  11. % Also don't define it in systemdict, because this leads some Adobe code
  12. % to think this interpreter is a distiller.
  13. % (If this interpreter really is a distiller, don't do this.)
  14. systemdict /pdfmark known not
  15.  { userdict /pdfmark { cleartomark } bind put } if
  16.  
  17. userdict /GS_PDF_ProcSet 127 dict dup begin
  18.  
  19. % ---------------- Abbreviations ---------------- %
  20.  
  21. /bdef { bind def } bind def
  22.  
  23. % ---------------- Graphics state stack ---------------- %
  24.  
  25. % PDF adds a number of parameters to the graphics state.
  26. % We implement this by pushing and popping a dictionary
  27. % each time we do a PDF gsave or grestore.
  28. % The keys in this dictionary are as follows:
  29. %    self            % identifies the dictionary as one of ours
  30. %    ClipRect        % (optional)
  31. %    Show
  32. %    TextSaveMatrix        % matrix at time of BT (iff within BT/ET)
  33. % (The following correspond directly to PDF state parameters.)
  34. %    AlphaIsShape
  35. %    FillConstantAlpha
  36. %    FillColor
  37. %    FillColorSpace
  38. %    FillOverprint
  39. %    SoftMask
  40. %    StrokeConstantAlpha
  41. %    StrokeColor
  42. %    StrokeColorSpace
  43. %    StrokeOverprint
  44. %    TextSpacing
  45. %    TextHScaling
  46. %    Leading
  47. %    TextFont
  48. %    TextLineMatrix
  49. %    TextMatrix
  50. %    TextRise
  51. %    TextRenderingMode
  52. %    WordSpacing
  53.  
  54. /nodict 1 dict def
  55. nodict /self { //nodict } executeonly put
  56. nodict readonly pop
  57.  
  58. /dictbeginpage {    % <initialdict> dictbeginpage -
  59.   //nodict 20 dict .copydict begin { def } forall
  60.   graphicsbeginpage textbeginpage
  61. } bdef
  62. /endpage {    % - endpage -
  63.   showpage end
  64. } bdef
  65.  
  66. /graphicsbeginpage {
  67.   initgraphics
  68.   currentdict /ClipRect .knownget { aload pop rectclip } if
  69.   0 g  0 G  false op  false OP  0 OPM
  70.   1 ca  1 CA  null SMask  false AIS  /Compatible BM  true TK
  71. } bdef
  72.  
  73. /gput        % <value> <key> gput -
  74.  { exch currentdict //nodict eq { /self dup load end 5 dict begin def } if
  75.         % If we're in a Level 1 system, we need to grow the
  76.         % dictionary explicitly.
  77.    currentdict length currentdict maxlength ge %eq
  78.     { currentdict dup length 3 mul 2 idiv 1 add dict .copydict end begin 
  79.     }
  80.    if def
  81.  } bdef
  82.  
  83. /q {
  84.   gsave //nodict begin
  85. } bdef
  86. % Some PDF files have excess Q operators!
  87. /Q {
  88.   currentdict /self .knownget { exec //nodict eq { end grestore } if } if
  89. } bdef
  90.  
  91. % ---------------- Color setting ---------------- %
  92.  
  93. /fcput        % <color> <colorspace> fcput -
  94.  { /FillColorSpace gput /FillColor gput
  95.  } bdef
  96. /scput        % <color> <colorspace> scput -
  97.  { /StrokeColorSpace gput /StrokeColor gput
  98.  } bdef
  99.  
  100. /csdevgray [/DeviceGray] readonly def
  101. /csdevrgb [/DeviceRGB] readonly def
  102. /csdevcmyk [/DeviceCMYK] readonly def
  103. /cspattern [/Pattern] readonly def
  104. /nullpattern1 mark
  105.    /PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 0 0]
  106.    /XStep 1 /YStep 1 /PaintProc { }
  107. .dicttomark readonly def
  108. /nullpattern2 nullpattern1 dup length dict copy readonly def
  109.  
  110. % Each entry in the color space dictionary is a procedure of the form
  111. %    <cspace> -proc- <cspace> <initial-color>
  112. /CSdict mark
  113.   /DeviceGray { pop //csdevgray 0 } bind
  114.   /DeviceRGB { pop //csdevrgb [0 0 0] cvx } bind
  115.   /DeviceCMYK { pop //csdevcmyk [0 0 0 1] cvx } bind
  116.   /CIEBasedA { 0 } bind
  117.   /CIEBasedABC { [0 0 0] cvx } bind
  118.   /ICCBased { [ 1 index 1 oget /N get { 0 } repeat ] cvx } bind
  119.   /Separation { 1 } bind
  120.   /DeviceN {    % What is the correct value??
  121.     [ 1 index 1 get length { 1 } repeat ] cvx
  122.   } bind
  123.   /Indexed { 0 } bind
  124.   /Pattern {
  125.     dup type /nametype eq 1 index length 1 eq or {
  126.       pop //cspattern //nullpattern1 matrix makepattern
  127.     } {
  128.       //nullpattern2 matrix makepattern 1 index 1 get csset
  129.         % Stack: patternspace nullpattern basecolor basespace
  130.       pop [ 3 1 roll dup type /arraytype eq { aload pop } if
  131.       counttomark -1 roll ] cvx
  132.     } ifelse
  133.   } bind
  134. .dicttomark readonly def
  135. /csset            % <cspace> csset <color> <cspace>
  136.  { dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch
  137.  } bdef
  138.  
  139. /g { //csdevgray fcput } bdef
  140. /G { //csdevgray scput } bdef
  141. /rg { 3 array astore cvx //csdevrgb fcput } bdef
  142. /RG { 3 array astore cvx //csdevrgb scput } bdef
  143. /k { 4 array astore cvx //csdevcmyk fcput } bdef
  144. /K { 4 array astore cvx //csdevcmyk scput } bdef
  145. /cs { csset fcput } bdef
  146. /CS { csset scput } bdef
  147. /ri { pop } bdef
  148. % We have to break up sc according to the number of operands.
  149. /sc1 { /FillColor gput } bdef
  150. /SC1 { /StrokeColor gput } bdef
  151. % We have to avoid storing into a color array associated with an outer
  152. % gsave level, so we do a kind of "copy on write".
  153. /sc* {
  154.   currentdict /FillColor .knownget {
  155.     astore pop
  156.   } {
  157.     /FillColor load length array astore cvx /FillColor gput
  158.   } ifelse
  159. } bdef
  160. /SC* {
  161.   currentdict /StrokeColor .knownget {
  162.     astore pop
  163.   } {
  164.     /StrokeColor load length array astore cvx /StrokeColor gput
  165.   } ifelse
  166. } bdef
  167.  
  168. % ---------------- Overprint/transparency setting ---------------- %
  169.  
  170. /op { /FillOverprint gput } bdef
  171. /OP { /StrokeOverprint gput } bdef
  172. /OPM {
  173.   /.setoverprintmode where { pop .setoverprintmode } { pop } ifelse
  174. } bdef
  175. /ca { /FillConstantAlpha gput } bdef
  176. /CA { /StrokeConstantAlpha gput } bdef
  177. /SMask { /SoftMask gput } bdef
  178. /AIS { /AlphaIsShape gput } bdef
  179. /BM {
  180.   /.setblendmode where {
  181.     pop [ exch dup type /nametype ne { aload pop } if /Normal ] {
  182.       { .setblendmode } .internalstopped not { exit } if pop
  183.     } forall
  184.   } {
  185.     pop
  186.   } ifelse
  187. } bdef
  188. /TK {
  189.   /.settextknockout where { pop .settextknockout } { pop } ifelse
  190. } bdef
  191.  
  192. % ---------------- Color installation ---------------- %
  193.  
  194. % Establish a given color (and color space) as current.
  195. /.settransparencyparams {    % <alpha> <smask> .settransparencyparams -
  196.   /.begintransparencymask where {
  197.     pop AlphaIsShape {
  198.       1 .setopacityalpha 0 .inittransparencymask exch .setshapealpha 1
  199.     } {
  200.       1 .setshapealpha 1 .inittransparencymask exch .setopacityalpha 0
  201.     } ifelse
  202.     % Set the soft mask by rendering the XObject.  Doing this every time
  203.     % is obviously very inefficient; we'll improve it later.
  204.     .settransparencymask    
  205.   } {
  206.     pop pop
  207.   } ifelse
  208. } bdef
  209. /.settransparencymask {        % <paramdict> <masknum> .settransparencymask -
  210.   exch dup null eq {
  211.     pop .inittransparencymask
  212.   } {
  213.     dup /Draw get exec
  214.   } ifelse
  215. } bdef
  216. % (Non-mask) images must execute setfillblend.
  217. /setfillblend {
  218.   FillOverprint setoverprint
  219.   FillConstantAlpha SoftMask .settransparencyparams
  220. } def
  221. /setfillstate {
  222.   FillColor FillColorSpace setgcolor setfillblend
  223. } def
  224. /setstrokestate {
  225.   StrokeColor StrokeColorSpace setgcolor StrokeOverprint setoverprint
  226.   StrokeConstantAlpha SoftMask .settransparencyparams
  227. } def
  228. /Cdict 15 dict dup begin    % <color...> <colorspace> -proc- -
  229.   /DeviceGray { pop setgray } bdef
  230.   /DeviceRGB { pop setrgbcolor } bdef
  231.   /DeviceCMYK { pop setcmykcolor } bdef
  232.   /CIEBasedA
  233.    { dup currentcolorspace eq { pop } { setcolorspace } ifelse setcolor } bdef
  234.   /CIEBasedABC /CIEBasedA load def
  235.   /CIEBasedDEF /CIEBasedA load def
  236.   /CIEBasedDEFG /CIEBasedA load def
  237.   /ICCBased /CIEBasedA load def
  238.   /Separation /CIEBasedA load def
  239.   /DeviceN /CIEBasedA load def
  240.   /Indexed /CIEBasedA load def
  241.   /Pattern
  242.    { dup currentcolorspace eq { pop } { setcolorspace } ifelse
  243.      dup /Matrix .knownget not { matrix } if
  244.      gsave DefaultMatrix setmatrix makepattern grestore setcolor
  245.    } bdef
  246. end def
  247. /setgcolor    % (null | <color...>) <colorspace> setgcolor -
  248.  { 1 index null eq
  249.     { pop pop }
  250.     { dup 0 get //Cdict exch get exec }
  251.    ifelse
  252.  } bdef
  253. /fsexec        % <fillop|strokeop> fsexec -
  254.  {        % Preserve the current point, if any.
  255.     { currentpoint } stopped
  256.     { $error /newerror false put   cvx exec }
  257.     { 3 -1 roll cvx exec moveto }
  258.    ifelse
  259.  } bdef
  260.  
  261. % ---------------- Path painting and clipping ---------------- %
  262.  
  263. /S { setstrokestate /stroke fsexec } bdef
  264. /f { setfillstate /fill fsexec } bdef
  265. /f* { setfillstate /eofill fsexec } bdef
  266. /n { newpath } bdef        % don't allow n to get bound in
  267. /s { closepath S } bdef
  268. /B { gsave setfillstate fill grestore S } bdef
  269. /b { closepath B } bdef
  270. /B* { gsave setfillstate eofill grestore S } bdef
  271. /b* { closepath B* } bdef
  272.  
  273. % Clipping:
  274.  
  275. /Wdict 4 dict dup begin
  276. /S { gsave setstrokestate stroke grestore n } bdef
  277. /f { gsave setfillstate fill grestore n } bdef
  278. /f* { gsave setfillstate eofill grestore n } bdef
  279. /n { end clip newpath } bdef
  280. end readonly def
  281. /W { //Wdict begin } bdef
  282. /W*dict 4 dict dup begin
  283. Wdict { def } forall
  284. /n { end eoclip newpath } bdef
  285. end readonly def
  286. /W* { //W*dict begin } bdef
  287.  
  288. % ---------------- Text control ---------------- %
  289.  
  290. /textbeginpage
  291.  { /TextSpacing 0 def        % 0 Tc
  292.    /TextLeading 0 def        % 0 TL
  293.    /TextRenderingMode 0 def    % 0 Tr
  294.    /TextRise 0 def        % 0 Ts
  295.    /WordSpacing 0 def        % 0 Tw
  296.    /TextHScaling 1.0 def    % 100 Tz
  297.    /TextFont null def
  298.    /Show { showfirst } def
  299.  } bdef
  300.  
  301. % Contrary to the statement in the PDF manual, BT and ET *can* be nested,
  302. % if the CharProc for a Type 3 font does a BT/ET itself.
  303. % Since we always call the CharProc inside a q/Q, we simply ensure that
  304. % the text state is saved and restored like the rest of the extended
  305. % graphics state.
  306.  
  307. /settextmatrix {
  308.   TextMatrix concat
  309.   TextHScaling 1 ne { TextHScaling 1 scale } if
  310.   TextRise 0 ne { 0 TextRise translate } if
  311.   TextFont dup null eq { pop } { setfont } ifelse
  312. } bdef
  313. /settextstate {
  314.     % The text state can be set even outside BT/ET.
  315.   currentdict /TextSaveMatrix known {
  316.     TextSaveMatrix setmatrix settextmatrix
  317.   } if
  318. } bdef
  319. /settextposition {
  320.         % Update the TextMatrix translation.
  321.   gsave TextSaveMatrix setmatrix
  322.   currentpoint TextMatrix 4 2 getinterval astore pop
  323.         % We would like to do "grestore currentpoint translate"
  324.         % here, but some PDF files set a singular text matrix
  325.         % (0 0 0 0 <x> <y> Tm), so we can't do this.
  326.   TextTempMatrix identmatrix setmatrix currentpoint
  327.   grestore
  328.   TextTempMatrix currentmatrix 4 2 getinterval astore pop
  329.   TextTempMatrix setmatrix
  330. } bdef
  331.  
  332. /BT {
  333.   currentdict /TextLineMatrix .knownget
  334.     { identmatrix pop TextMatrix identmatrix pop }
  335.     { matrix /TextLineMatrix gput matrix /TextMatrix gput }
  336.   ifelse
  337.   { showfirst } /Show gput
  338.   currentdict /TextSaveMatrix .knownget not {
  339.     matrix dup /TextSaveMatrix gput
  340.   } if currentmatrix pop settextmatrix
  341.   matrix /TextTempMatrix gput        % see settextposition
  342. } bdef
  343. /ET {
  344.   TextRenderingMode 4 ge { clip newpath } if
  345.   TextSaveMatrix setmatrix
  346.   currentdict /TextSaveMatrix undef
  347. } bdef
  348. /Tc { /TextSpacing gput { showfirst } /Show gput } bdef
  349. /TL { /TextLeading gput } bdef
  350. /Tr { /TextRenderingMode gput { showfirst } /Show gput } bdef
  351. /Ts { /TextRise gput settextstate } bdef
  352. /Tw { /WordSpacing gput { showfirst } /Show gput } bdef
  353. /Tz { 100 div /TextHScaling gput settextstate} bdef
  354.  
  355. % ---------------- Font control ---------------- %
  356.  
  357. /Tf {        % <font> <scale> Tf -
  358.   dup 1 eq { pop } { scalefont } ifelse
  359.   /TextFont gput settextstate
  360. } bdef
  361.  
  362. % Read a CFF font.
  363. /FRD        % <resname> <file> FRD -
  364.  { /FontSetInit /ProcSet findresource begin true ReadData
  365.  } bdef
  366.  
  367. % Copy a font, removing its FID.  If changed is true, also remove
  368. % the UniqueID and XUID, if any.  If the original dictionary doesn't have
  369. % the keys being removed, don't copy it.
  370. /.copyfontdict        % <font> <changed> .copyfontdict <dict>
  371.  { 1 index /FID known
  372.    1 index { 2 index /UniqueID known or 2 index /XUID known or } if
  373.     {        % We add 1 to the length just in case the original
  374.         % didn't have a FID.
  375.       exch dup length 1 add dict exch
  376.        {        % Stack: changed newfont key value
  377.      1 index /FID eq 4 index
  378.       { 2 index /UniqueID eq or 2 index /XUID eq or }
  379.      if not { 3 copy put } if pop pop
  380.        }
  381.       forall exch
  382.     }
  383.    if pop
  384.  } bdef
  385.  
  386. % Insert a new Encoding or Metrics into a font if necessary.
  387. % Return a possibly updated font, and a flag to indicate whether
  388. % the font was actually copied.
  389. /.updatefontmetrics {    % <font> <Metrics|null> .updatefontmetrics
  390.             %   <font'> <copied>
  391.   dup null ne {
  392.     exch true .copyfontdict dup /Metrics 4 -1 roll put true
  393.   } {
  394.     pop false
  395.   } ifelse
  396. } bdef
  397. /.updatefontencoding {    % <font> <Encoding|null> .updatefontencoding
  398.             %   <font'> <copied>
  399.   dup null ne { dup 2 index /Encoding get ne } { false } ifelse {
  400.     exch false .copyfontdict dup /Encoding 4 -1 roll put true
  401.   } {
  402.     pop false
  403.   } ifelse
  404. } bdef
  405. /.updatefont {        % <font> <Encoding|null> <Metrics|null> .updatefont
  406.             %   <font'> <copied>
  407.   3 -1 roll exch .updatefontmetrics
  408.             % Stack: enc|null font' copied
  409.   3 1 roll exch .updatefontencoding 3 -1 roll or
  410. } bdef
  411.  
  412. % ---------------- Text positioning ---------------- %
  413.  
  414. /Td {
  415.   TextLineMatrix transform TextLineMatrix 4 2 getinterval astore pop
  416.   TextLineMatrix TextMatrix copy pop settextstate
  417. } bdef
  418. /TD { dup neg /TextLeading gput Td } bdef
  419. /T* { 0 TextLeading neg Vexch Td } bdef
  420. /Tm {
  421.   TextLineMatrix astore TextMatrix copy pop settextstate
  422. } bdef
  423.  
  424. % ---------------- Text painting ---------------- %
  425.  
  426. /Vexch {
  427.   rootfont /WMode .knownget { 1 eq { exch } if } if
  428. } bind def
  429.  
  430. /textrenderingprocs [        % (0 is handled specially)
  431.     % Painting-only modes
  432.    { tf } { tS } { tB } { tn }
  433.     % Clipping modes
  434.    { gsave tf grestore tW }
  435.    { gsave tS grestore tW }
  436.    { gsave tB grestore tW }
  437.    { tW }
  438. ] readonly def
  439. /setshowstate
  440.  { WordSpacing 0 eq TextSpacing 0 eq and
  441.     { TextRenderingMode 0 eq
  442.        { { setfillstate show } }
  443.        { { false charpath textrenderingprocs TextRenderingMode get exec } }
  444.       ifelse
  445.     }
  446.     { TextRenderingMode 0 eq
  447.        { WordSpacing 0 eq
  448.           { { setfillstate TextSpacing 0 Vexch 3 -1 roll ashow } }
  449.       { TextSpacing 0 eq
  450.             { { setfillstate WordSpacing 0 Vexch 32 4 -1 roll widthshow } }
  451.             { { setfillstate WordSpacing 0 Vexch 32
  452.                  TextSpacing 0 Vexch 6 -1 roll awidthshow } }
  453.         ifelse
  454.       }
  455.      ifelse
  456.        }
  457.        { { WordSpacing TextSpacing
  458.             % Implement the combination of t3 and false charpath.
  459.             % Note that we must use cshow for this, because we
  460.             % can't parse multi-byte strings any other way.
  461.             % Stack: string xword xchar
  462.         { pop pop (x) dup 0 3 index put false charpath
  463.             % Stack: xword xchar ccode
  464.              3 copy 32 eq { add } { exch pop } ifelse 0 Vexch rmoveto pop
  465.         }
  466.        4 -1 roll cshow pop pop
  467.        textrenderingprocs TextRenderingMode get exec
  468.      }
  469.        }
  470.       ifelse
  471.     }
  472.    ifelse /Show gput
  473.  } bdef
  474. /showfirst { setshowstate Show } def
  475.  
  476. /Tj {
  477.   0 0 moveto Show settextposition
  478. } bdef
  479. /' { T* Tj } bdef
  480. /" { exch Tc exch Tw T* Tj } bdef
  481. /TJ {
  482.   0 0 moveto {
  483.     dup type /stringtype eq {
  484.       Show
  485.     } { -1000 div
  486.       currentfont /ScaleMatrix .knownget { 0 get mul } if
  487.       0 Vexch rmoveto
  488.     } ifelse
  489.   } forall settextposition
  490. } bdef
  491.  
  492. /tf { setfillstate currentpoint fill moveto } bdef
  493. /tn { currentpoint newpath moveto } bdef
  494. % For stroking characters, temporarily restore the graphics CTM so that
  495. % the line width will be transformed properly.
  496. /Tmatrix matrix def
  497. /tS
  498.  { setstrokestate
  499.    currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix stroke
  500.    setmatrix moveto
  501.  } bdef
  502. /tB { gsave tf grestore tS } bdef
  503. % This does the wrong thing if there have been multiple text operations
  504. % within a single BT/ET pair, but it's a start.
  505. /tW { } bdef
  506.  
  507. end readonly put        % GS_PDF_ProcSet
  508.  
  509. .setglobal
  510.